#include "./Base/stdafx.h"
#include "./Base/GameEngine.h"
#include "Game.h"
#include "./Base/Light.h"
#include "./Base/Camera.h"
#include "./Base/DXDevice.h"
#include "./Base/DirectInput.h"
#include "./MySql/mysql.h"
#include "./Physx/PhysX.h"
#include "./Meshes/ModelLib.h"
#include "./Effects/EffectLib.h"
#include "./Effects/EffectShadow.h"
#include "./Meshes/Terrain/TerrainFlat.h"
#include "./Meshes/obj/OBJMesh.h"
#include "./Meshes/Mesh.h"
#include "./Time/Time.h"
#include <boost/foreach.hpp>
#include "./PhysX/PhysXObject.h"
#include "./Level/LevelLoader.h"
#include "./Base/StringUtil.h"

#include "./Animatie/Animation.h"
#include "./Animatie/Skeleton.h"
#include "./Ini/IniFile.h"
#include "./Character/Character.h"

#define SHADOW_ENABLED

Game* Game::m_Singleton = NULL;

Game* Game::GetSingleton()
{
	if(!m_Singleton)
		m_Singleton = new Game();
	return m_Singleton;
}

Game::Game()
{
	TIME;
	MODELLIB;
	EFFECTLIB;
}

Game::~Game()
{
	delete MODELLIB;
	delete EFFECTLIB;
	delete m_Character;
	delete PhysX::GetSingleton();
	delete m_Timer;
	delete m_Meshes;
	delete m_Skeleton;
	delete m_AnimWalk;
	delete m_Effect;
	BOOST_FOREACH( PhysXObject* obj, m_PhysXObjects) delete obj;
	Time::Destroy();
}

void Game::Init()
{
	PhysX::GetSingleton()->Init();

	m_Character = new Character(-20, 10, -20, 10, 2);
	DXDEVICE->SetupCamera(D3DXVECTOR3(-20, 10, -20), D3DXVECTOR3(0,10,0));
	//DXDEVICE->GetCamera()->SetSpeed(100);
	DXDEVICE->GetLight().pos = D3DXVECTOR3(100, 100, 100);

	// Disable Camera movement
	DXDEVICE->GetCamera()->EnableCameraMovement(false);

	m_Effect = new EffectShadow(_T("./Shaders/ShadowVolume10.fx"));
	
	m_Timer = new Timer(0, 0, 20);
	m_Timer->AddListener(this);
	m_Meshes = new Mesh();

	LevelLoader::Load(_T("./Levels/test.lvl"), m_Meshes, m_PhysXObjects);
	m_Box = m_Meshes->GetId(_T("Kist"));
	m_BoxPos = m_Meshes->GetMesh(m_Box)->GetTranslation();

	m_Meshes->CreateFlatTerrain(_T("./Textures/floor_diffuse.dds"), 2000);
	m_Meshes->CreateSkybox(_T("./Textures/Skybox_Sky.bmp"), 1000);

	m_AnimWalk = new Animation(_T("./models/animation/walkbloky.anim"));
	m_Skeleton = new Skeleton(_T("./models/Skeleton/test.rig"));
	m_Skeleton->SetTranslate(D3DXVECTOR3(0, 10, 10));
	m_Skeleton->SetRotation(D3DXVECTOR3(-(float)D3DX_PI/2, 0, 0));
	m_Skeleton->SetSpeed(2);
	m_Skeleton->PlayAnimation(m_AnimWalk);

}

void Game::Tick(float dTime)
{
	PhysX::GetSingleton()->FetchResults();

	DirectInput::GetSingleton()->Poll();

	if(DirectInput::GetSingleton()->KeyDown(DIK_RETURN))
		m_Meshes->AddForce(D3DXVECTOR3(0, 30, 0));

	m_Character->Tick(dTime);

	m_Meshes->Tick(dTime);
	BOOST_FOREACH(PhysXObject* obj, m_PhysXObjects) obj->Tick(dTime);

	m_Skeleton->Tick(dTime);

	DXDEVICE->GetCamera()->SetPos(D3DXVECTOR3(m_Character->GetPosition().x, m_Character->GetPosition().y, m_Character->GetPosition().z));

	m_Timer->Tick(dTime);

	PhysX::GetSingleton()->Simulate(dTime);
}

void Game::Paint()
{	
	m_Meshes->Render();

#ifdef _DEBUG
	tstring speedText = _T("POS\nX = ") + StringUtil::ToString(m_Character->GetPosition().x);
	speedText +=  _T("\nY = ") + StringUtil::ToString(m_Character->GetPosition().y);
	speedText +=  _T("\nZ = ") + StringUtil::ToString(m_Character->GetPosition().z);
	speedText += _T("\nSPEED\nX = ") + StringUtil::ToString(m_Character->GetSpeed().x);
	speedText +=  _T("\nY = ") + StringUtil::ToString(m_Character->GetSpeed().y);
	speedText +=  _T("\nZ = ") + StringUtil::ToString(m_Character->GetSpeed().z);

	DXDEVICE->DrawText(speedText, 10, 10);
#endif // _DEBUG
}

void Game::KeyPressed(WPARAM key)
{
	if(key == VK_ESCAPE)
		PostMessage(GAME_ENGINE->GetWindow(), WM_DESTROY, NULL, NULL);

}

void Game::OnResize()
{

}

void Game::CallAction(Timer *callerPtr)
{
	if(callerPtr == m_Timer)
	{
		LOG(_T("Box Reset"));
		m_Meshes->GetMesh(m_Box)->SetTranslate(m_BoxPos);
		m_Timer->Reset();
	}
}